package postgres

import (
	"context"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"ozonTest/internal/config"
	"sort"
	"strings"

	"github.com/jackc/pgx/v5"
)

// ConnectToDB устанавливает соединение с базой данных PostgreSQL.
func ConnectToDB(cfg config.DBConfig) *pgx.Conn {
	// Формируем строку подключения к базе данных из переменных окружения.
	url := fmt.Sprintf("%v://%v:%v@%v:%v/%v",
		cfg.GetDBDriver(),
		cfg.GetDBUser(),
		cfg.GetDBPassword(),
		cfg.GetDBHost(),
		cfg.GetDBPort(),
		cfg.GetDBName(),
	)
	// Устанавливаем соединение с базой данных.
	log.Println(url)
	connect, err := pgx.Connect(context.Background(), url)
	if err != nil {
		log.Printf("Не удалось подключиться к базе данных: %v\n", err)
		os.Exit(1)
	}

	return connect
}

func RunMigrations(conn *pgx.Conn, migrationsDir string) error {
	files, err := ioutil.ReadDir(migrationsDir)
	if err != nil {
		return fmt.Errorf("failed to read migrations directory: %v", err)
	}

	var migrationFiles []string
	for _, file := range files {
		if strings.HasSuffix(file.Name(), ".down.sql") {
			migrationFiles = append(migrationFiles, file.Name())
		}
	}

	sort.Strings(migrationFiles)

	for _, file := range migrationFiles {
		err := executeMigrationFile(conn, migrationsDir+"/"+file)
		if err != nil {
			return err
		}
	}

	migrationFiles = nil
	for _, file := range files {
		if strings.HasSuffix(file.Name(), ".up.sql") {
			migrationFiles = append(migrationFiles, file.Name())
		}
	}

	sort.Strings(migrationFiles)

	for _, file := range migrationFiles {
		err := executeMigrationFile(conn, migrationsDir+"/"+file)
		if err != nil {
			return err
		}
	}

	return nil
}

func executeMigrationFile(conn *pgx.Conn, filePath string) error {
	file, err := os.Open(filePath)
	if err != nil {
		return fmt.Errorf("failed to open migration file %s: %v", filePath, err)
	}
	defer file.Close()

	content, err := ioutil.ReadAll(file)
	if err != nil {
		return fmt.Errorf("failed to read migration file %s: %v", filePath, err)
	}

	_, err = conn.Exec(context.Background(), string(content))
	if err != nil {
		return fmt.Errorf("failed to execute migration file %s: %v", filePath, err)
	}

	log.Printf("Executed migration: %s\n", filePath)
	return nil
}
